
// All the values of the DATA table are merged into the datastorage plug when this method is activated
// Everything below this line effectively overrides the PLUG table
// This means that all functions inside the DATA table can be accessed using plugs.Call, even if not for data storage purposes
// Use with caution!

DATA.InternalName = "file" -- Internal name of this data method

DATA.PrintName = "Serverside Data Storage (File)" -- Append our method name onto the plug name
DATA.MethodName = "File Storage" -- Name that this method presents itself to the client

// Below we define all hard coded data file paths
// In other data storage methods, these could be things like table names for mysql
local LogDir = "gmanage/logs/"
local PlayerDir = "gmanage/players/"
local GroupDir = "gmanage/ugrps/"

local DataFile = "gmanage/serverdata.txt"
local LimitFile = "gmanage/limits.txt"

// * -- Since I wrote this system after file data storage has already been implemented, I am adding backwards compatibility -- *
// Note: This is now obsolete, but may be useful so I'll leave it in
local OverrideTable = {
	logmessage = true, -- Log Message function ("LogMessage")
	playerdata = true, -- SavePlayerData & LoadPlayerData function ("SavePlayerData"), ("LoadPlayerData")
	serverdata = true, -- ReadServerData & SaveServerData function ("ReadServerData"), ("SaveServerData")
	groupdata = true, -- ReadUsergroups function ("ReadUsergroups"), ("SaveUsergroups"), ("DeleteUsergroup")
}
function DATA:Overrided( id )
	return OverrideTable[ logmessage ] -- If this returns true, the source function is ended before anything is done and our version gets called
end

// Logs a message to file
function DATA:LogMessage( id, message )
	local lg = ""
	if (file.Exists( LogDir .. id .. ".txt" )) then lg = file.Read( LogDir .. id .. ".txt" ) end
	local line = "[" .. os.date() .. "] " .. message
	file.Write( LogDir .. id .. ".txt", lg .. "\n" .. line )
end

// Loads the data of a player
function DATA:LoadPlayerData( ply )
	local filename = PlayerDir .. string.Replace( ply:SteamID(), ":", "" ) .. ".txt"
	local dat = {}
	local b, res = pcall( glon.decode, file.Read( filename ) )
	if (b) then return res end
end

// Saves the data of a player
function DATA:SavePlayerData( ply )
	local filename = PlayerDir .. string.Replace( ply:SteamID(), ":", "" ) .. ".txt"
	local b, res = pcall( glon.encode, ply._DAT )
	if (b) then file.Write( filename, res ) else ErrorNoHalt( res ) end
end

// Reads the core server data
function DATA:ReadServerData()
	if (!file.Exists( DataFile )) then return {} end
	local b, res = pcall( glon.decode, file.Read( DataFile ) )
	if (b) then return res end
	return {}
end

// Saves the core server data
function DATA:SaveServerData()
	local b, res = pcall( glon.encode, plugs.Call( "GetServerData" ) or {} )
	if (b) then file.Write( DataFile, res ) end
end

// Reads usergroup data
function DATA:ReadUsergroups()
	local tmp = {}
	for _, v in pairs( file.Find( GroupDir .. "*.txt" ) ) do
		local filename = GroupDir .. v
		local txt = file.Read( filename )
		local tbl = glon.decode( txt )
		tbl._FILENAME = filename
		tmp[ tbl.ClassName ] = tbl
		Msg( "Loaded usergroup '" .. tbl.ClassName .. "'!\n" )
	end
	return tmp
end

// Saves usergroup data
function DATA:SaveUsergroups()
	for _, grp in pairs( plugs.Call( "GetUGS" ) ) do
		if (!grp.Hard) then
			file.Write( grp._FILENAME, glon.encode( grp ) )
		end
	end
	Msg( "Usergroups saved!\n" )
end

// Deletes a usergroup
function DATA:DeleteUsergroup( name )
	local fn = plugs.Call( "GetUsergroupData", name )._FILENAME
	if (file.Exists( fn )) then file.Delete( fn ) end
end

// Reads the limit data
function DATA:ReadLimits()
	if (!file.Exists( LimitFile )) then return end
	local txt = file.Read( LimitFile )
	local b, res = pcall( glon.decode, txt )
	if (b) then
		Msg( "Limits loaded!\n" )
		return res
	else
		ErrorNoHalt( res )
	end
end

// Saves the limit data
function DATA:SaveLimits()
	local b, res = pcall( glon.encode, plugs.Call( "GetLimits" ) )
	if (b) then
		file.Write( LimitFile, res )
		Msg( "Limits saved!\n" )
	else
		Msg( "Limits NOT saved! (" .. tostring( res ) .. ")\n" )
	end
end